package pro.shushi.pamirs.demo.core.action;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.boot.base.enmu.BaseExpEnumerate;
import pro.shushi.pamirs.core.common.enmu.TimeUnitEnum;
import pro.shushi.pamirs.demo.api.enumeration.DemoExpEnumerate;
import pro.shushi.pamirs.demo.api.enumeration.ItemStatusEnum;
import pro.shushi.pamirs.demo.api.model.DemoItem;
import pro.shushi.pamirs.demo.api.service.DemoItemService;
import pro.shushi.pamirs.demo.core.mq.DemoItemMQProducer;
import pro.shushi.pamirs.demo.core.task.DemoItemScheduleTaskAction;
import pro.shushi.pamirs.framework.connectors.data.sql.Pops;
import pro.shushi.pamirs.framework.connectors.data.sql.query.LambdaQueryWrapper;
import pro.shushi.pamirs.framework.connectors.data.sql.query.QueryWrapper;
import pro.shushi.pamirs.meta.annotation.Action;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.dto.condition.Pagination;
import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.common.exception.PamirsException;
import pro.shushi.pamirs.meta.common.lambda.LambdaUtil;
import pro.shushi.pamirs.meta.constant.FunctionConstants;
import pro.shushi.pamirs.meta.enmu.ActionContextTypeEnum;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;
import pro.shushi.pamirs.meta.enmu.ViewTypeEnum;
import pro.shushi.pamirs.meta.util.JsonUtils;
import pro.shushi.pamirs.middleware.schedule.api.ScheduleAction;
import pro.shushi.pamirs.middleware.schedule.eunmeration.TaskType;
import pro.shushi.pamirs.trigger.model.ExecuteTaskAction;
import pro.shushi.pamirs.trigger.service.ExecuteTaskActionService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static pro.shushi.pamirs.meta.enmu.FunctionOpenEnum.*;

@Slf4j
@Component
@Model.model(DemoItem.MODEL_MODEL)
public class DemoItemAction {

    @Autowired
    private DemoItemMQProducer demoItemMQProducer;
    @Autowired
    private ExecuteTaskActionService executeTaskActionService;

    @Autowired
    private DemoItemService demoItemService;

    /**
     * 自定义构造方法，如：界面设计器提交数据-选择的提交函数，新增时系统会调用construct
     * @param data
     * @return
     */
    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type = FunctionTypeEnum.QUERY)
    public DemoItem construct(DemoItem data) {
        // TODO: 2023/11/9 可增加处理逻辑
        return data;
    }

    /**
     * 自定义LambdaQueryWrapper查询List
     * @param dataId
     * @return
     */
    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    public List<DemoItem> listByCondition(Long dataId){
        LambdaQueryWrapper<DemoItem> wrapper = Pops.<DemoItem>lambdaQuery()
                .from(DemoItem.MODEL_MODEL)
                .eq(DemoItem::getCreateUid, PamirsSession.getUserId())//当前用户
                .in(DemoItem::getCategoryId, new ArrayList<Long>(){{this.add(111111L);this.add(22222L);}})
                .and(_wrapper->{
                    _wrapper.ne(DemoItem::getStatus, ItemStatusEnum.INACTIVE);
                    _wrapper.or(_wrapper1->_wrapper1.isNull(DemoItem::getItemPrice));
                });

        return demoItemService.queryListByWrapper(wrapper);
    }

    /**Start--以下是重写覆盖系统默认增删改查的实现方式---------------------------------------------------------------------*/
    @Function.Advanced(type = FunctionTypeEnum.QUERY, managed = true)
    @Function.fun(FunctionConstants.queryByEntity)
    @Function(openLevel = {LOCAL, REMOTE, API})
    public DemoItem queryOne(DemoItem query) {
        if(query.getId() == null){
            throw PamirsException.construct(DemoExpEnumerate.DEMO_ITEM_ID_ISNULL).errThrow();
        }
        return demoItemService.queryOne(query);
    }

    @Action.Advanced(name = FunctionConstants.create, managed = true)
    @Action(displayName = "确定", summary = "创建", bindingType = ViewTypeEnum.FORM)
    @Function(name = FunctionConstants.create)
    @Function.fun(FunctionConstants.create)
    public DemoItem create(DemoItem data) {
        return demoItemService.create(data);
    }

    @Function.Advanced(type = FunctionTypeEnum.UPDATE)
    @Action.Advanced(name = FunctionConstants.update, managed = true)
    @Action(displayName = "确定", summary = "修改", bindingType = ViewTypeEnum.FORM)
    @Function(name = FunctionConstants.update)
    @Function.fun(FunctionConstants.update)
    public DemoItem update(DemoItem data) {
        //测试自定义发送mq消息
//        try {
//            demoItemMQProducer.sendNormalMessage(JsonUtils.toJSONString(data), String.valueOf(System.currentTimeMillis()));
//        } catch (Exception e) {
//            log.error("演示发送消息失败", e);
//        }

        //测试自定义异步任务
//        executeTaskActionService.submit((ExecuteTaskAction) new ExecuteTaskAction()
//                .setBizId(data.getId())
//                .setTaskType(TaskType.SERIAL_REMOTE_SCHEDULE_TASK.getValue())
//                .setNextRetryTimeUnit(TimeUnitEnum.SECOND)
//                .setNextRetryTimeValue(5)
//                .setLimitRetryNumber(10)
//                .setDisplayName("商品测试任务")
//                .setExecuteNamespace(DemoItemScheduleTaskAction.FUN_NAMESPACE)
//                .setExecuteFun(ScheduleAction.DEFAULT_METHOD)
//                .setContext(JSON.toJSONString(data)));
        return demoItemService.update(data);
    }

    @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表")
    @Function.fun(FunctionConstants.queryPage)
    @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API})
    public Pagination<DemoItem> queryPage(Pagination<DemoItem> page, IWrapper<DemoItem> queryWrapper) {


        Map<String,Object> queryData = queryWrapper.getQueryData();
        String itemName = null;
        String itemNameField = LambdaUtil.fetchFieldName(DemoItem::getName);
        if(queryData != null && queryData.containsKey(itemNameField) && queryData.get(itemNameField) != null) {
            itemName = String.valueOf(queryData.get(itemNameField));
        }

        LambdaQueryWrapper<DemoItem> qw = ((QueryWrapper<DemoItem>) queryWrapper).lambda();
//        qw.eq(DemoItem::getCreateUid, PamirsSession.getUserId());
        if(StringUtils.isNoneBlank(itemName)) qw.like(DemoItem::getName,itemName);
        return demoItemService.queryPage(page, qw);
    }

    @Function.Advanced(type = FunctionTypeEnum.DELETE)
    public DemoItem deleteOne(DemoItem data) {
        return demoItemService.deleteOne(data);
    }

    @Function.Advanced(type = FunctionTypeEnum.DELETE)
    @Function.fun(FunctionConstants.deleteWithFieldBatch)
    @Function(name = FunctionConstants.delete)
    @Action(displayName = "删除", contextType = ActionContextTypeEnum.SINGLE_AND_BATCH)
    public List<DemoItem> delete(List<DemoItem> dataList) {
        return demoItemService.delete(dataList);
    }


    @Action(displayName = "上架",bindingType = ViewTypeEnum.TABLE,contextType = ActionContextTypeEnum.SINGLE)
    @Action.Advanced(invisible = "context.activeRecord.status == 'ACTIVE'")
    public DemoItem itemActive(DemoItem data) {
        DemoItem update = new DemoItem();
        update.setId(data.getId());
        update.setStatus(ItemStatusEnum.ACTIVE);
        update.updateById();
        return data;
    }

    @Action(displayName = "下架",bindingType = ViewTypeEnum.TABLE,contextType = ActionContextTypeEnum.SINGLE)
    @Action.Advanced(invisible = "context.activeRecord.status == 'INACTIVE'")
    public DemoItem itemInActive(DemoItem data) {
        DemoItem update = new DemoItem();
        update.setId(data.getId());
        update.setStatus(ItemStatusEnum.INACTIVE);
        update.updateById();
        return data;
    }
}
